package utsc.apps.utschedule.widget;

import java.lang.ref.WeakReference;
import utsc.apps.utschedule.R;
import utsc.apps.utschedule.classes.Course;
import utsc.apps.utschedule.ui.interfaces.ViewCallable;
import utsc.apps.utschedule.util.AppUtils;
import utsc.apps.utschedule.util.TimetableHelper;
import utsc.apps.utschedule.widget.BlockView;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.LayerDrawable;
import android.text.TextPaint;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.widget.LinearLayout;
import android.widget.TextView;

/**
 * A custom layout widget that shows some basic information about a {@link Course course}.
 * @author Wenbin
 *
 */
public class EventBlockView extends BlockView implements OnLongClickListener{

	private Course _course;
	private TextView _txtStartTime;
	private TextView _txtEndTime;
	private TextView _txtBody;
	//private LinearLayout _eventBlockLayout;
	private TextPaint _defaultTextPaint;
	private boolean _showToday;
	private boolean _editMode;
	private boolean _editEndTime=true;
	//private float _lastX;
	private float _lastY;
	private int _viewIndex;
	private ViewCallable<Course> _updateCallable;
	private float _pixelPerMs;
	private int _color;
	
	public EventBlockView(Context context, int _viewIndex,int _columnPosition,/*int width, int height,*/ Course course,boolean showDay) {
		super(context);
		if (course == null) {
			throw new IllegalArgumentException(
					"You must supply a valid course object to this view!");
		}
		this._course = course;
		this._viewIndex=_viewIndex;
		this._columnPosition=_columnPosition;
		this.set_showToday(showDay);
		if (showDay) {
			LayoutInflater.from(context).inflate(R.layout.eventblockview, this,true);
		}else {
			LayoutInflater.from(context).inflate(R.layout.eventblockview_day, this,true);
		}
		
		setupContentView();
		
		setOnLongClickListener(this);
	}

	
	public Course get_course() {
		return _course;
	}

	public void set_course(Course _course) {
		this._course = _course;
		setupContentView();
		//removeAllViewsInLayout();
		requestLayout();
	}

	public int get_viewIndex() {
		return _viewIndex;
	}
	
	@Override
	protected void setupContentView() {
		
		
		if (_txtStartTime==null) {
			setOrientation(LinearLayout.VERTICAL);
			setWeightSum(4);
			//=(LinearLayout) findViewById(R.id.eventblock_layout);
			
			_txtStartTime=(TextView) findViewById(R.id.eventblock_starttime);
			_txtEndTime=(TextView) findViewById(R.id.eventblock_endtime);
			_txtBody=(TextView) findViewById(R.id.eventblock_body);
		}
		
		_txtStartTime.setText(TimetableHelper.getTimeString(_course.get_startTime()));
		_txtEndTime.setText(TimetableHelper.getTimeString(_course.get_endTime()));
		//String shortName=_course.get_shortName();
		StringBuilder stringBuilder=new StringBuilder(_course.toString());
		stringBuilder.append("\n");
		stringBuilder.append(_course.get_location());
		String bodyText=stringBuilder.toString();
		_txtBody.setText(bodyText);
		
		if (_course.get_color()!=_color) {
			WeakReference<LayerDrawable> bg=AppUtils.getColorCustomizableDrawable(getContext(), R.drawable.btn_block, _course.get_color(), 1,_course.is_tutorial()?255:0);
			bg.get().getDrawable(0).setAlpha(AppUtils.ALPHA);
			setBackgroundDrawable(bg.get());
			_color=_course.get_color();
			if (Math.abs(AppUtils.getBrightnessDifferences(Color.WHITE, _course.get_color()))>=AppUtils.BLACK_WHITE_BRIGHTNESS_THRESHOLD) {
				_txtStartTime.setTextColor(Color.WHITE);
				_txtEndTime.setTextColor(Color.WHITE);
				_txtBody.setTextColor(Color.WHITE);
			}else {
				_txtStartTime.setTextColor(Color.DKGRAY);
				_txtEndTime.setTextColor(Color.DKGRAY);
				_txtBody.setTextColor(Color.DKGRAY);
			}
		}
		//adjustFontSizeToFit();
	}
	/*
	private void adjustFontSizeToFit(){
		final int availableWidth=getWidth()-_paddingOffset*2;
		
		final String txt1=_txtEndTime.getText().toString();
		final String txt2=_txtStartTime.getText().toString();
		final String txt=(txt1.length()>txt2.length()?txt1:txt2);
		if (_defaultTextPaint==null) {
			_defaultTextPaint=_txtEndTime.getPaint();
		}
		final float defaultFontWidth=_defaultTextPaint.measureText(txt);//txtBound.width();
		final float fontsizeScale=1-(defaultFontWidth-availableWidth)/(float)defaultFontWidth;
		
		if (defaultFontWidth>availableWidth) {
			final int adjustedSize=(int)(_txtStartTime.getTextSize()*fontsizeScale);
			_txtStartTime.setTextSize(TypedValue.COMPLEX_UNIT_PX, adjustedSize);
			_txtEndTime.setTextSize(TypedValue.COMPLEX_UNIT_PX, adjustedSize);
		}
	}*/
	
	/*
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		setMeasuredDimension(resolveSize(getWidth()-_paddingOffset*2, widthMeasureSpec), resolveSize(getHeight()-_paddingOffset*2, heightMeasureSpec));
	}*/
	
	@Override
	protected void onLayout(boolean changed, int left, int top, int right,
			int bottom) {
		if (_editMode) {
			measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
		}
		super.onLayout(changed,0+_paddingOffset, 0+_paddingOffset, getWidth()-_paddingOffset, getHeight()-_paddingOffset);
	}

	public boolean is_showToday() {
		return _showToday;
	}

	public void set_showToday(boolean _showToday) {
		this._showToday = _showToday;
	}

	@Override
	public boolean onLongClick(View v) {
		_editMode=true;
		final float heightY=getHeight();
		final float centerY=heightY/2;
		if (centerY>_lastY) {
			_editEndTime=false;
		}else {
			_editEndTime=true;
		}
		getParent().requestDisallowInterceptTouchEvent(true);
		getParent().bringChildToFront(this);
		return true;
	}
	

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int action=event.getAction();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			//final float x=event.getX();
			final float y=event.getY();
			//_lastX=x;
			_lastY=y;
			break;
		case MotionEvent.ACTION_UP:
			
			if (_editMode) {
				_editMode=false;
				TimeBlockLayout parent=(TimeBlockLayout) getParent();
				//adjustFontSizeToFit();
				parent.requestDisallowInterceptTouchEvent(false);
				parent.updateCourseLayout(_viewIndex,_editEndTime);
				
				if (_updateCallable!=null) {
					_updateCallable.updateDB(_course);					
				}
				//parent.invalidate();
			}
			
			break;
		case MotionEvent.ACTION_MOVE:
			final float moveY=event.getY();
			if (_editMode) {
				float difference=moveY-_lastY;
						if (_editEndTime) {
							final long starttime=_course.get_startTime();
							final long newEndtime=updateCourseTime(difference,_editEndTime);
							if (newEndtime-starttime>2700000) {
								TimeBlockLayout parent=(TimeBlockLayout) getParent();
								_course.set_endTime(newEndtime);
								
								_txtEndTime.setText(TimetableHelper.getTimeString(_course.get_endTime()));
								parent.updateCourseLayout(_viewIndex,_editEndTime);
								_lastY=moveY;
							}
						}else {
							final long endtime=_course.get_endTime();
							final long newStarttime=updateCourseTime(difference,_editEndTime);
							if (endtime-newStarttime>2700000) {
								if (Math.abs(_course.get_startTime()-newStarttime)>60000) {
									TimeBlockLayout parent=(TimeBlockLayout) getParent();
									_course.set_startTime(newStarttime);
									_txtStartTime.setText(TimetableHelper.getTimeString(_course.get_startTime()));
									parent.updateCourseLayout(_viewIndex,_editEndTime);
									_lastY=moveY-difference;
								}
								
							}
						}
					
			}
			
			break;//return true;
	
		default:
			break;
		}
		return super.onTouchEvent(event);
	}
	
	public void set_updateCallable(ViewCallable<Course> _updateCallable) {
		this._updateCallable = _updateCallable;
	}

	private long updateCourseTime(float difference,boolean updateEndtime){
		long end=0;
		if (updateEndtime) {
			end=_course.get_endTime();	
		}else {
			end=_course.get_startTime();
		}
		
		if (_pixelPerMs==0) {
			final int height=getHeight();
			long start=0;
			if (updateEndtime) {
				start=_course.get_startTime();
			}else {
				start=_course.get_endTime();
			}
			
			_pixelPerMs=(float)Math.abs((end-start))/height;
		}
		
		long rawTime=(long)(difference*_pixelPerMs+end);
		
		//rawTime=(rawTime-Math.abs((rawTime-(rawTime-59999))-59999));
		return rawTime;//c.getTimeInMillis();
	}
	

}
